package com.cssw.fyzb.busi.api.pay;

import com.alibaba.fastjson.JSON;
import com.cssw.fyzb.busi.config.TpsClient;
import com.cssw.fyzb.busi.model.tps.Tf56PayQuickSignDataVo;
import com.cssw.fyzb.busi.model.tps.Tf56PayQuickSignVo;
import com.cssw.fyzb.busi.service.pay.QuickPayService;
import com.cssw.fyzb.busi.service.user.UserService;
import com.cssw.fyzb.busi.util.BizUtil;
import com.cssw.fyzb.busi.util.Bizs;
import com.cssw.fyzb.core.exception.BizException;
import com.cssw.fyzb.core.model.dodb.QuickRequestLog;
import com.cssw.fyzb.core.model.dodb.User;
import com.cssw.fyzb.core.model.dodb.UserQuickSign;
import com.cssw.fyzb.core.model.vo.pay.QuickSignVo;
import com.cssw.fyzb.core.model.vo.pay.UserQuickSignVo;
import com.cssw.fyzb.core.util.StringUtil;
import com.ijpay.core.kit.PayKit;
import com.ydn.appserver.Action;
import com.ydn.appserver.Request;
import com.ydn.appserver.Response;
import com.ydn.appserver.annotations.Function;
import com.ydn.appserver.annotations.Parameter;
import com.ydn.appserver.annotations.Type;
import com.ydn.simplecache.SimpleCache;
import com.ydn.simplelock.SimpleLock;
import com.ydn.simplelock.SimpleLockFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author: yangyiqun
 * @Date: 2020/7/14 22:10
 */

@Function(description = "快捷签约信息", parameters = {
        @Parameter(name = "userId", type = Type.String, description = "用户标识", required = true),
        @Parameter(name = "bankCode", type = Type.String, description = "银行编码", required = true),
        @Parameter(name = "bankName", type = Type.String, description = "银行名称", required = true),
        @Parameter(name = "cardNo", type = Type.String, description = "卡号", required = true),
        @Parameter(name = "mobile", type = Type.String, description = "银行预约手机号码", required = true),
        @Parameter(name = "userName", type = Type.String, description = "真实姓名", required = true),
        @Parameter(name = "idCard", type = Type.String, description = "身份证号码", required = true),
})
@Component
public class QuickSign implements Action {

    private static final Logger logger = LoggerFactory.getLogger(QuickSign.class);

    @Autowired
    private TpsClient tpsClient;

    @Autowired
    private QuickPayService quickPayService;

    @Autowired
    private UserService userService;

    @Autowired
    private SimpleCache simpleCache;

    @Autowired
    private SimpleLockFactory simpleLockFactory;

    @Override
    public Response execute(Request request) throws Exception {
        Long userId = request.getLong("userId");
        String bankCode = request.getString("bankCode");
        String bankName = request.getString("bankName");
        String cardNo = request.getString("cardNo");
        String mobile = request.getString("mobile");
        String userName = request.getString("userName");
        String idCard = request.getString("idCard");

        SimpleLock simpleLock = simpleLockFactory.getLock("USER_" + userId);
        try {

            simpleLock.acquire();

            User user = userService.getById(userId);
            if (user.isFrozen()) {
                BizUtil.exception("用户状态不正确");
            }

            UserQuickSign cardNoQuickSign = quickPayService.getUserQuickSignByUIdAndCardNo(userId, cardNo);
            if (null != cardNoQuickSign) {
                BizUtil.exception("您已经签约过该卡号");
            }

            request.setParameter("userId", userId);
            request.setParameter("bankCode", bankCode);
            request.setParameter("bankName", bankName);
            request.setParameter("cardNo", cardNo);
            request.setParameter("mobile", mobile);
            String orderNo = PayKit.generateStr();

            Tf56PayQuickSignDataVo dataVo = quickSign(cardNo, userName, idCard, mobile, orderNo, userId);

            QuickSignVo quickSignVo = new QuickSignVo();
            quickSignVo.setCardNo(cardNo);
            quickSignVo.setBankCode(bankCode);
            quickSignVo.setBankName(bankName);
            quickSignVo.setIdCard(idCard);
            quickSignVo.setMobile(mobile);
            quickSignVo.setRealName(userName);
            quickSignVo.setOrderNo(orderNo);
            quickSignVo.setUserId(userId);
            quickSignVo.setBusiNo(dataVo.getBusinessrecordnumber());
            if (null == dataVo) {
                BizUtil.exception("签约失败！");
            }
            if (StringUtil.isEmpty(dataVo.getCertcode()) && StringUtil.isEmpty(dataVo.getBusinessrecordnumber())){
                BizUtil.exception("签约失败！");
            }

            String certCode = dataVo.getCertcode();

            Map result = new HashMap();
            result.put("orderNo", orderNo);

            //如果签约过快捷支付，提示异常
            if (StringUtil.isNotEmpty(certCode)) {
                if (user.getMobile().equals(mobile)) {
                    //如果签约手机号和本用户是同一个手机号码，绑定签约信息
                    quickPayService.saveUserQuickSign(userId, quickSignVo.getCardNo(), quickSignVo.getRealName(),
                            quickSignVo.getBankName(), quickSignVo.getBankCode(), dataVo.getCertcode(),
                            quickSignVo.getMobile(), quickSignVo.getOrderNo(), quickSignVo.getIdCard());
                }
                result.put("certCode", certCode);

                BizUtil.exception("该卡号已经签约过快捷支付！");
            }

            simpleCache.put("TF56PAYQUICKSIGN_" + userId, JSON.toJSONString(quickSignVo));

            return Response.success().put("data", result);
        } catch (Exception e) {
            if (e instanceof BizException) {
                BizException be = (BizException) e;
                return Response.fail(be.getErrMsg(), be.getErrCode());
            }
            logger.error("", e);
            return Response.fail("签约失败！");
        } finally {
            try {
                simpleLock.release();
            } catch (Exception e) {
                logger.error("", e);
            }
        }
    }

    private void saveQuickRequestLog(Long userId, String orderNo, String busiNo, String errorCode, String errorMsg, Map reqParam, Tf56PayQuickSignVo vo) {
        if (errorMsg != null && errorMsg.length() > 200) {
            errorMsg = errorMsg.substring(0, 200);
        }
        quickPayService.saveQuickRequestLog(userId, orderNo, busiNo, QuickRequestLog.TYPE_SIGN, errorCode, errorMsg, JSON.toJSONString(reqParam), JSON.toJSONString(vo));
    }

    private Tf56PayQuickSignDataVo quickSign(String cardNo, String realName, String idCard, String mobile, String orderNo, Long userId) {
        Map<String, Object> param = new HashMap<>();
        param.put("cardNo", cardNo);
        param.put("realName", realName);
        param.put("idCard", idCard);
        param.put("mobile", mobile);
        param.put("orderNo", orderNo);
        param.put("userId", userId);

        Tf56PayQuickSignVo vo = null;
        try {
            vo = tpsClient.tf56PayQuickSign(cardNo, realName, idCard, mobile, orderNo, userId);

        } catch (Exception e) {
            if (e instanceof BizException) {
                BizException be = (BizException) e;
                saveQuickRequestLog(userId, orderNo, "", String.valueOf(be.getErrCode()), be.getErrMsg(), param, vo);
            } else {
                saveQuickRequestLog(userId, orderNo, "", "-99", e.getMessage(), param, vo);
            }

            BizUtil.exception("签约快捷支付失败！");
        }
        if (!(isSuccess(vo))) {
            logger.error(">>>>" + vo);
            saveQuickRequestLog(userId, orderNo, "", getErrorCode(vo), getErrorMsg(vo), param, vo);
            //如果业务不成功，则返回第三方的错误信息
            if (!"GPBIZ_00".equals(vo.getBiz_code())) {
                BizUtil.exception(vo.getBiz_msg());
            }

            BizUtil.exception("快捷签约失败，请确认信息是否正确！");
        }

        Tf56PayQuickSignDataVo dataVo = vo.getDataVo();
        if (null == dataVo) {
            saveQuickRequestLog(userId, orderNo, dataVo.getBusinessrecordnumber(), "-1", "数据对象为空", param, vo);
            BizUtil.exception("快捷签约失败，请确认信息是否正确！");
        }

        saveQuickRequestLog(userId, orderNo, dataVo.getBusinessrecordnumber(), getErrorCode(vo), getErrorMsg(vo), param, vo);
        return dataVo;
    }


    private boolean isSuccess(Tf56PayQuickSignVo vo) {
        return "GP_00".equals(vo.getCode()) && "GPBIZ_00".equals(vo.getBiz_code());
    }

    private String getErrorCode(Tf56PayQuickSignVo vo) {
        if (!"GP_00".equals(vo.getCode())) {
            return vo.getCode();
        }
        if (!"GPBIZ_00".equals(vo.getBiz_code())) {
            return vo.getBiz_code();
        }

        return "0";
    }

    private String getErrorMsg(Tf56PayQuickSignVo vo) {
        if (!"GP_00".equals(vo.getCode())) {
            return vo.getMsg();
        }
        if (!"GPBIZ_00".equals(vo.getBiz_code())) {
            return vo.getBiz_msg();
        }

        return "success";
    }
}